﻿using DDD.DomainModel;
using System;
using System.Collections.Generic;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Text;

namespace DDD.Infrastructure.Repositories
{


    internal class EdmRepositoryTransactionContext : IRepositoryTransactionContext
    {

        private ObjectContext objContext;

        private Dictionary<Type, object> repositoryCache = new Dictionary<Type, object>();

        public EdmRepositoryTransactionContext(ObjectContext objContext)
        {

            this.objContext = objContext;

        }

        #region IRepositoryTransactionContext Members

        public IRepository<TEntity> GetRepository<TEntity>() where TEntity : IAggregateRoot
        {
            var entityType = typeof(TEntity);
            bool canRegister = entityType.BaseType != typeof(EntityObject);
            if (!canRegister)
            {
                throw new ArgumentException("TEntity is not allow register!must is son of System.Data.Objects.DataClasses.EntityObject");
            }

            if (repositoryCache.ContainsKey(entityType))
            {

                return (IRepository<TEntity>)repositoryCache[typeof(TEntity)];

            }

            IRepository<TEntity> repository = new EdmRepository<TEntity>(this.objContext);

            this.repositoryCache.Add(typeof(TEntity), repository);

            return repository;

        }

        public void BeginTransaction()
        {

            // We do not need to begin a transaction here because the object context,

            // which would handle the transaction, was created and injected into the

            // constructor by Castle Windsor framework.

        }

        public void Commit()
        {

            this.objContext.SaveChanges();

        }

        public void Rollback()
        {

            // We also do not need to perform the rollback operation because

            // entity framework will handle this for us, just when the execution

            // point is stepping out of the using scope.

        }

        #endregion


        #region IDisposable Members

        public void Dispose()
        {

            this.repositoryCache.Clear();

            this.objContext.Dispose();

        }

        #endregion

    }


}
